const { User } = require('../model/user')
const { Topic } = require('../model/topics')
// const {Avatar} = require('../model/avatar')
const {Level} = require('../model/level')
const bcrypt = require('bcrypt')
const config = require('../config')
const jwt = require('jsonwebtoken')
const {getUserLever} = require('../utils')
const moment = require('moment-timezone');
//注册用户
exports.register = async (req, res, next) => {
    try {
        let { phone, password } = req.body
        let user = await User.findOne({ phone })
        if (user) return res.status(200).json({
            code: 400,
            msg: "号码已经被注册",
            data: { phone }
        })
        const salt = await bcrypt.genSalt(10)
        password = await bcrypt.hash(password, salt)
        let randomStr = Math.random().toString(36).slice(-8)
        user = new User({
            phone,
            password,
            nickname: '新用户' + randomStr,
            createdAt:moment().tz("Asia/Shanghai").format('YYYY/MM/DD HH:mm:ss')
        })
        await user.save()
        res.status(200).json({
            code: 200,
            msg: "注册成功",
            data: { phone }
        })
    } catch (err) {
        next(err)
    }
}
//获取用户列表
exports.getUserList = async (req, res, next) => {
    try {
        const userList = await User.find().populate("avatar")
        if (!userList) return res.status(200).json({
            code: 400,
            msg: '获取用户列表失败'
        })
        res.status(200).json({
            code: 200,
            msg: '查询用户列表成功',
            data: userList
        })
    } catch (err) {
        next(err)
    }
}
//根据Token解密获取用户信息
exports.getUserByToken = async (req, res, next) => {
    try {
        let token = req.headers.authorization
        let spaceIndex = token.indexOf(' ')
        token = token.substring(spaceIndex + 1, token.length)
        token = jwt.verify(token, config.secret)
        const userId = token._id
        const user = await User.findById(userId).select("+praiseCount +following +createdAt +gender +experience").populate('avatar')
        if (!user) return res.status(200).json({
            code: 400,
            msg: '用户不存在'
        })
        let follower = await User.find({ following: user._id })
        let followerList = []
        follower.forEach((item,index) => {
            followerList[index] = item._id
        })
        user._doc["fansList"] = followerList

        if (user.experience) {
					let levelNum = getUserLever(user.experience);
					let { level, url } = await Level.findOne({ level: levelNum });
					user._doc["level"] = {
						level: level,
						url: url,
					};
				} else {
					user._doc["level"] = {
						level: "unknown",
						url: `/level/level1.png`,
					};
				}

        res.status(200).json({
            code: 200,
            msg: '获取用户数据成功',
            data: user
        })
    }
    catch (err) {
        next(err)
    }
}

//获取指定用户信息
exports.getUser = async (req, res, next) => {
    try {
        const userId = req.params.id
        let follower = await User.find({ following: req.params.id })
        if(!follower) return res.status(200).json({
            code:400,
            msg:"获取用户粉丝列表失败"
        })
        let user = await User.findById(userId).select("+praiseCount +following +createdAt +gender +experience").populate('avatar')
        if (!user) return res.status(200).json({
            code: 400,
            msg: '用户不存在'
        })
        let followerList = []
        follower.forEach((item,index) => {
            followerList[index] = item._id
        })
        user._doc["fansList"] = followerList

        if (user.experience) {
					let levelNum = getUserLever(user.experience);
					let { level, url } = await Level.findOne({ level: levelNum });
					user._doc["level"] = {
						level: level,
						url: url,
					};

				} else {
					user._doc["level"] = {
						level: "unknown",
						url: `/level/level1.png`,
					};
				}

        res.status(200).json({
            code: 200,
            msg: '查询指定用户成功',
            data: user
        })
    } catch (err) {
        next(err)
    }
}
//修改用户信息
exports.updateUser = async (req, res, next) => {
    try {
        let userId = req.params.id
        let body = req.body
        // const salt = await bcrypt.genSalt(10)
        // body.password = await bcrypt.hash(body.password, salt)

        const data = await User.findByIdAndUpdate(userId, body)

        // res.send('修改用户')
        if (!data) return res.status(200).json({
            code: 400,
            msg: '更新信息失败'
        })
        res.status(200).json({
            code: 200,
            msg: '更新信息成功',
            data: body

        })
    } catch (err) {
        //通过错误处理中间件处理错误
        next(err)
    }
}

//修改登录用户信息
exports.updateLoginUser = async (req, res, next) => {
    try {
        let userId = req.userData._id
        let body = req.body
        // const salt = await bcrypt.genSalt(10)
        // body.password = await bcrypt.hash(body.password, salt)

        const data = await User.findByIdAndUpdate(userId, body)
        if (!data) return res.status(400).json({
            code: 400,
            msg: '更新信息失败'
        })
        res.status(200).json({
            code: 200,
            msg: '更新信息成功',
            data: body
        })
    } catch (err) {
        //通过错误处理中间件处理错误
        next(err)
    }
}
//修改用户头像
exports.updateUserAvatar = async (req,res,next) => {
    try {
        let userId = req.userData._id
        let avatarId = req.params.id

        const data = await User.findByIdAndUpdate(userId, {
            avatar:avatarId
        }).populate("avatar")
        if (!data) return res.status(400).json({
            code: 400,
            msg: '修改头像失败'
        })
        res.status(200).json({
            code: 200,
            msg: '修改头像成功',
            data: data.avatar
        })
    } catch (err) {
        next(err)
    }
}


//关注
exports.follow = async (req, res, next) => {
    try {
        let userId = req.userData._id
        let followId = req.params.id
        const user = await User.findById(userId.toString()).select("+following")
        if (user._id == followId) {
            return res.status(200).json({
                code: 400,
                msg: '关注失败,你不能关注自己',
                data: user
            })
        }
        //关注过了直接返回
        if (user.following.map(id => id.toString()).includes(followId)) return res.status(200).json({
            code: 400,
            msg: '该用户已关注，关注失败'
        })
        user.following.push(followId)
        await user.save()
        res.status(200).json({
            code: 200,
            msg: "关注成功",
            data: user.following
        })
    } catch (err) {
        next(err)
    }
}
//取消关注
exports.unfollow = async (req, res, next) => {
    try {
        let userId = req.userData._id
        const user = await User.findById(userId.toString()).select("+following")
        const index = user.following.map(id => id.toString()).indexOf(req.params.id)
        if (index == -1) return res.status(200).json({
            code: 400,
            msg: "未关注该用户，取消关注失败"
        })

        user.following.splice(index, 1)
        await user.save()
        res.status(200).json({
            code: 200,
            msg: "取消关注成功"
        })
    } catch (err) {
        next(err)
    }
}
//获取用户关注列表
exports.getFollowingList = async (req, res, next) => {
    try {
        let userId = req.params.id
        const list = await User.findById(userId).select("+following")
        .populate({
            path:'following',
            select:"+experience",
            populate:{
                path:"avatar"
            }
        })
        
        if (!list) {
            return res.status(200).json({
                code: 400,
                msg: '获取用户关注列表失败'
            })
        }

        list:await Promise.all(list.following.map(async (item,index,array) => {
            if(item.experience){
                let levelNum= getUserLever(item.experience)
                let {level,url} =await Level.findOne({level:levelNum})
                item._doc["level"] = {
                    level:level,
                    url:url
                }
                return item
            } else {
                item._doc["level"] = {
                    level:'unknown',
                    url:`/level/level1.png`
                }
                return item
            }
        }))
        res.status(200).json({
            code: 200,
            msg: "获取用户关注列表成功",
            data: list.following
        })
    } catch (err) {
        next(err)
    }
}

//获取用户粉丝列表
exports.getFollowers = async (req, res, next) => {
    try {
        const users = await User.find({ following: req.params.id }).select("+experience").populate("avatar")

        if (!users) return res.status(200).json({
            code: 400,
            msg: "查询用户粉丝列表失败"
        })
        users:await Promise.all(users.map(async (item,index,array) => {
            if(item.experience){
                let levelNum= getUserLever(item.experience)
                let {level,url} =await Level.findOne({level:levelNum})
                item._doc["level"] = {
                    level:level,
                    url:url
                }
                return item
            } else {
                item._doc["level"] = {
                    level:'unknown',
                    url:`/level/level1.png`
                }
                return item
            }
        }))
        res.status(200).json({
            code: 200,
            msg: '查询用户粉丝列表成功',
            data: users
        })
    } catch (err) {
        next(err)
    }
}


//点赞帖子
exports.likeTopic = async (req, res, next) => {
    try {
        let userId = req.userData._id
        const followId = req.params.id
        const user = await User.findById(userId.toString()).select("+likingTopics")
        //如果没有点赞则点赞
        if (!user.likingTopics.map(id => id.toString()).includes(followId)) {
            user.likingTopics.push(followId)
            await user.save()
            const changeTopic=await Topic.findByIdAndUpdate(req.params.id, { $inc: { praise: +1 } }).select("+user")
            await User.findByIdAndUpdate(changeTopic.user, { $inc: { praiseCount: +1 } })
            await User.findByIdAndUpdate(userId, { $inc: { experience: +2 } })
            await User.findByIdAndUpdate(changeTopic.user, { $inc: { experience: +2 } })
            res.status(200).json({
                code: 200,
                msg: "点赞成功,经验+2",
                data: {
                    id: req.params.id
                }
            })
        } else {
            res.status(200).json({
                code: 400,
                msg: "点赞失败",
                data: {
                    id: req.params.id
                }
            })
        }
    } catch (err) {
        next(err)
    }
}

//取消点赞帖子
exports.unLikeTopic = async (req, res, next) => {
    try {
        let userId = req.userData._id
        const user = await User.findById(userId.toString()).select("+likingTopics")
        const index = user.likingTopics.map(id => id.toString()).indexOf(req.params.id)
        if (index > -1) {
            user.likingTopics.splice(index, 1)
            await user.save()
            const changeTopic = await Topic.findByIdAndUpdate(req.params.id, { $inc: { praise: -1 } })
            await User.findByIdAndUpdate(changeTopic.user, { $inc: { praiseCount: -1 } })
            res.status(200).json({
                code: 200,
                msg: "操作成功",
                data: {
                    id: req.params.id
                }
            })
        } else {
            res.status(200).json({
                code: 400,
                msg: "操作失败",
                data: {
                    id: req.params.id
                }
            })
        }
    } catch (err) {
        next(err)
    }
}


//获取我的点赞列表
exports.getMyLikingTopics = async (req, res, next) => {
    try {
        if (!req.loginuser) return res.status(200).json({
            code: 200,
            msg: '获取点赞帖子列表失败，请先登录',
            data: []
        })
        let userId = req.loginuser._id
        const user =await User.findById(userId).select("+likingTopics").populate("likingTopics")
        if (!user) return res.status(200).json({
            code: 400,
            msg: "获取点赞帖子列表失败",
        })
        res.status(200).json({
            code: 200,
            msg: '获取点赞帖子列表成功',
            data: user.likingTopics
        })
    } catch (err) {
        next(err)
    }
}

//收藏帖子
exports.collectingTopic = async (req, res, next) => {
    try {
        let userId = req.userData._id
        const followId = req.params.id
        const user = await User.findById(userId.toString()).select("+collectingTopics")
        if (user.collectingTopics.map(id => id.toString()).includes(followId)) return res.status(200).json({
            code: 400,
            msg: '已收藏，收藏失败'
        })
        user.collectingTopics.push(followId)
        await user.save()
        await Topic.findByIdAndUpdate(req.params.id, { $inc: { collected: +1 } })
        res.status(200).json({
            code: 200,
            msg: "收藏成功",
            data: {
                id: req.params.id
            }
        })
    } catch (err) {
        next(err)
    }
}
//取消收藏帖子
exports.uncollectingTopic = async (req, res, next) => {
    try {
        let userId = req.userData._id
        const user = await User.findById(userId.toString()).select("+collectingTopics")
        const index = user.collectingTopics.map(id => id.toString()).indexOf(req.params.id)
        if (index == -1) return res.status(200).json({
            code: 400,
            msg: "未收藏，取消收藏失败"
        })

        user.collectingTopics.splice(index, 1)
        await user.save()
        await Topic.findByIdAndUpdate(req.params.id, { $inc: { collected: -1 } })

        res.status(200).json({
            code: 200,
            msg: "取消收藏成功",
            data: {
                id: req.params.id
            }
        })
    } catch (err) {
        next(err)
    }
}

//获取指定用户收藏帖子列表
exports.collectingTopicList = async (req, res, next) => {
    try {
        const userId = req.params.id
        let user = await User.findById(userId).select("+collectingTopics")
        .populate({
            path:"collectingTopics",
            populate: {
                path:"images user",
                select:"+experience",
                populate:{
                    path:"avatar",
                    strictPopulate: false
                }
            },
            
        })
        if (!user) return res.status(200).json({
            code: 400,
            msg: "查询用户收藏列表失败"
        })
        let collectingTopic = user.collectingTopics
        collectingTopic:await Promise.all(collectingTopic.map(async (item,index,array) => {
            if(item.user.experience){
                let levelNum= getUserLever(item.user.experience)
                let {level,url} =await Level.findOne({level:levelNum})
                item.user._doc["level"] = {
                    level:level,
                    url:url
                }
                return item
            } else {
                item.user._doc["level"] = {
                    level:'unknown',
                    url:`/level/level1.png`
                }
                return item
            }
        }))
        res.status(200).json({
            code: 200,
            msg: '获取用户收藏列表成功',
            data: collectingTopic
            
        })
    } catch (err) {
        next(err)
    }
}

//获取我的收藏列表
exports.getMyCollectingTopics = async (req, res, next) => {
    try {
        const userId = req.userData._id
        const user =await User.findById(userId).select("+collectingTopics")
        .populate({
            path:"collectingTopics",
            populate: "images user",
            select:"+experience"
        })
        if (!user) return res.status(200).json({
            code: 400,
            msg: "获取收藏列表失败",
        })
        res.status(200).json({
            code: 200,
            msg: '获取收藏列表成功',
            data: user.collectingTopics

        })
    } catch (err) {
        next(err)
    }
}
exports.getMyLikingComments = async (req,res,next) => {
    const user = await User.findById(req.userData._id).select("+likingReplies")
    if(!user) return res.status(200).json({
        code:400,
        msg: "获取我的点赞评论列表失败"
    })
    res.status(200).json({
        code :200,
        msg:"获取我的点赞评论列表成功",
        data:user.likingReplies
    })
}